package com.zoffy.wmsbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zoffy.wmsbackend.common.ErrorCode;
import com.zoffy.wmsbackend.exception.BusinessException;
import com.zoffy.wmsbackend.model.entity.User;
import com.zoffy.wmsbackend.model.vo.UserVO;
import com.zoffy.wmsbackend.security.UserDetail;
import com.zoffy.wmsbackend.service.UserService;
import com.zoffy.wmsbackend.mapper.UserMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.stereotype.Service;

/**
 * @author 86170
 * @description 针对表【tb_user(用户表)】的数据库操作Service实现
 * @createDate 2025-01-02 01:34:40
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {
    private final  String USER_LOGIN_STATE_KEY = "USER_LOGIN_STATE_KEY";
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private SecurityContextRepository securityContextRepository;

    @Override
    public boolean registry(String userAccount,String userPassword,String checkPassword) {


        //账号密码长度校验
        if (userAccount.length() < 5) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号小于5位");
        }
        if (userPassword.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码小于8位");
        }
        //两次密码应该相同
        if (!userPassword.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次密码不相同");
        }
        //检验账号是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", userAccount);
        long count = this.count(queryWrapper);
        if (count >= 1) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该账号已存在");
        }
        //创建账号
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserName("用户"+ RandomStringUtils.random(8,true,true));
        user.setUserPassword(passwordEncoder.encode(userPassword));
        return this.save(user);
    }

    @Override
    public UserVO login(String userAccount, String userPassword, HttpServletRequest request, HttpServletResponse response) {
        try{
            Authentication authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(userAccount,userPassword));
            SecurityContext context = SecurityContextHolder.getContext();
            context.setAuthentication(authentication);
            securityContextRepository.saveContext(context,request,response);
        }catch (BadCredentialsException badCredentialsException){
            throw new BusinessException(ErrorCode.LOGIN_PARAMS_ERROR);
        }
        LambdaQueryWrapper<User> wrapper= Wrappers.lambdaQuery();
        wrapper.eq(User::getUserAccount,userAccount);
        return UserVO.obj2Vo(this.getOne(wrapper));
    }

    @Override
    public UserVO current() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        System.out.println(authentication.getPrincipal());
        try{
            User user = ((UserDetail) authentication.getPrincipal()).getUser();
            return UserVO.obj2Vo(getById(user));
        }catch (Exception e){

        }
//        return UserVO.obj2Vo(getById(user));
        return new UserVO();
    }
}




